//
//  searchCombox.swift
//  searchComboxDemo
//
//  Created by 陆永权 on 15/9/2.
//  Copyright (c) 2015年 Xunilu. All rights reserved.
//

import UIKit


public class searchCombox: UIView, UITextFieldDelegate, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate {

    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect) {
        // Drawing code
    }
    */
    var comboxTextField : UITextField
    var searchTableView : UITableView?
    var searchTextField : UISearchBar?
    public var width : CGFloat?
    public var height : CGFloat?
    public var alwaysShow = true
    public var chooserBorderColor : UIColor?
    public var chooserBackgroundColor : UIColor?
    public var chooserBorderWidth : CGFloat?
    public var chooserSeparatorColor : UIColor?
    public var isShowSearchFirst = true
    public var dataSource : UITableViewDataSource?
    public var isMatchFunc : ((String,String)->Bool)?
    public var isAutoComplete = true
    
    var searchString : String?
    var isShowChoose = false
    var isOutTextField = false
    var isOutSearchBar = true
    var reuseId : String?
    let cellMapper = NSMutableDictionary()
    //let getCell : (Int, Int) -> UITableViewCell? = memoize {row, section in return nil}
    
    
    public required init(coder aDecoder: NSCoder) {
        comboxTextField = UITextField()
        super.init(coder: aDecoder)
        let frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
        comboxTextField.frame = frame
        comboxTextField.borderStyle = UITextBorderStyle.RoundedRect
        
        comboxTextField.delegate = self
        comboxTextField.userInteractionEnabled = true
        self.addSubview(comboxTextField)
        
    }
    public override init(frame: CGRect) {
        let frameTextField = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
        comboxTextField = UITextField(frame: frameTextField)

        super.init(frame: frame)
        comboxTextField.borderStyle = UITextBorderStyle.RoundedRect
        comboxTextField.delegate = self

        self.addSubview(comboxTextField)
        
        
    }
   
    public override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        comboxTextField.resignFirstResponder()
    }
    
    
    public func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
        isOutTextField = false
        showChoose(textField)
        return true
    }
    public func textFieldDidEndEditing(textField: UITextField) {
        isOutTextField = true
        hideChoose(false)
    }
    func hideChoose(noCheck:Bool){
        if isShowChoose && isOutTextField && isOutSearchBar || noCheck{
            isShowChoose = false
            searchTextField!.removeFromSuperview()
            searchTableView!.removeFromSuperview()
            self.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y , width: comboxTextField.frame.width, height: comboxTextField.frame.height)
            comboxTextField.resignFirstResponder()
        }
    }
    
    
    func showChoose(textField: UITextField) {
        if isShowChoose {
            return
        }
        

        if (count(textField.text) == 0 || alwaysShow) && !isShowChoose {
            isShowChoose = true
            if let searchTableValue = searchTableView {
                if let searchTextFieldValue = searchTextField {
                    textField.superview!.addSubview(searchTextField!)
                    textField.superview!.addSubview(searchTableView!)

                    self.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y , width: searchTextField!.frame.width, height: comboxTextField.frame.height + searchTextField!.frame.height + searchTableView!.frame.height)
                    self.superview!.bringSubviewToFront(self)
                    return
                }
            }
            
            let x = textField.frame.origin.x
            var width = self.width == nil ? textField.frame.size.width : self.width!
            var height = self.height == nil ? textField.frame.size.height * 5 : self.height!
            var borderColor = self.chooserBorderColor == nil ? UIColor.lightGrayColor() : self.chooserBorderColor!
            var borderWidth:CGFloat = self.chooserBorderWidth == nil ? 1 : self.chooserBorderWidth!
            var backgroundColor = self.chooserBackgroundColor == nil ? UIColor.whiteColor() : self.chooserBackgroundColor!
            var separatorColor = self.chooserSeparatorColor == nil ? UIColor.lightGrayColor() : self.chooserSeparatorColor!

            var y1 = textField.frame.origin.y + textField.frame.size.height
            var y = y1 + height
            if isShowSearchFirst {
                y = textField.frame.origin.y + textField.frame.size.height
                y1 = textField.frame.origin.y + textField.frame.size.height * 2
            }
            
            searchTextField = UISearchBar(frame: CGRect(x: x, y: y, width: width, height: textField.frame.height))
            searchTextField!.delegate = self
            searchTextField!.layer.borderColor = borderColor.CGColor
            searchTextField!.layer.borderWidth = borderWidth
            searchTextField!.barTintColor = borderColor
            searchTextField!.delegate = self
            
            searchTableView = UITableView(frame: CGRect(x: x, y: y1, width: width, height: height))
            searchTableView!.layoutMargins = UIEdgeInsetsZero
            searchTableView!.separatorInset.left = 0
            searchTableView!.separatorColor = separatorColor
            searchTableView!.rowHeight = searchTextField!.frame.height
            searchTableView!.layer.borderColor = borderColor.CGColor
            searchTableView!.layer.borderWidth = borderWidth
            searchTableView!.layer.backgroundColor = backgroundColor.CGColor
            searchTableView!.dataSource = self
            searchTableView!.delegate = self
            
            textField.superview!.addSubview(searchTextField!)
            textField.superview!.addSubview(searchTableView!)

            self.frame = CGRect(x: self.frame.origin.x, y: self.frame.origin.y , width: width, height: textField.frame.height + searchTextField!.frame.height + searchTableView!.frame.height)
            self.superview!.bringSubviewToFront(self)

        }
        
    }
    public func searchBarShouldBeginEditing(searchBar: UISearchBar) -> Bool {
        self.isOutSearchBar = false
        return true
    }
    public func searchBarTextDidEndEditing(searchBar: UISearchBar) {
        self.isOutSearchBar = true
        hideChoose(false)
    }
    
    public func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if let selfDataSource = self.dataSource {
            var count =  selfDataSource.tableView(tableView, numberOfRowsInSection: section)
            var i = count-1
            
            if let searchStringValue = self.searchString {
                while i>=0 {
                    let cell = selfDataSource.tableView(tableView, cellForRowAtIndexPath: NSIndexPath(forRow: i, inSection: section))
                    let valueString = cell.textLabel!.text!
                    if !isMatch(searchStringValue, withValue: valueString) {
                        count--
                    }
                    i--
                }
            }
            
            if count==1 && isAutoComplete {
                self.tableView(tableView, didSelectRowAtIndexPath : NSIndexPath(forRow: 0, inSection: section))
            }
            return count
        } else {
            return 0
        }
    }
    func isMatch(value1:String, withValue value2:String) -> Bool {
        if let funcValue = isMatchFunc {
            return funcValue(value1, value2)
        } else {
            return value2.hasPrefix(value1)
        }
    }
    
    public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        if let selfDataSource = self.dataSource {
            var valueString = ""
            var i = 0
            var cell = selfDataSource.tableView(tableView, cellForRowAtIndexPath: indexPath)
            if let searchStringValue = searchString {
                if let cellIndex = cellMapper[indexPath] as? NSIndexPath {
                    
                    return self.dataSource!.tableView(tableView, cellForRowAtIndexPath: cellIndex)
                    
                }
                if indexPath.row > 0 {
                    let cellLast = self.tableView(tableView, cellForRowAtIndexPath: NSIndexPath(forRow: indexPath.row - 1, inSection: indexPath.section))
                    i = (cellMapper[NSIndexPath(forRow: indexPath.row - 1, inSection: indexPath.section)] as! NSIndexPath).row - 1
                    do {
                        cell = selfDataSource.tableView(tableView, cellForRowAtIndexPath: NSIndexPath(forRow:i, inSection: indexPath.section))
                        i++
                    } while cellLast.textLabel!.text != cell.textLabel!.text
                }
                do {
                
                    cell = selfDataSource.tableView(tableView, cellForRowAtIndexPath: NSIndexPath(forRow: i, inSection: indexPath.section))
                    valueString = cell.textLabel!.text!
                    i++
                } while !isMatch(searchStringValue, withValue: valueString) && i < selfDataSource.tableView(tableView, numberOfRowsInSection: indexPath.section)
                
            }
            cellMapper[indexPath] = NSIndexPath(forRow: i-1, inSection: indexPath.section)
            return cell
        } else {
            return UITableViewCell()
        }
    }
    
    public func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let cell = self.tableView(tableView, cellForRowAtIndexPath: indexPath)
        comboxTextField.text = cell.textLabel!.text
        hideChoose(true)
    }
    
    public func searchBarSearchButtonClicked(searchBar: UISearchBar) {
        searchString = searchBar.text
        cellMapper.removeAllObjects()
        self.searchTableView!.reloadData()
        
    }
    
    public func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
        if searchBar.text == "" {
            searchString = nil
            cellMapper.removeAllObjects()
            self.searchTableView!.reloadData()
        }
    }
    
}
